/**
@author		Jong Min, Lee
@date		  02/07/2014
@breif		toolbar property

copyright(c) Tae Young Soft. All right reserved. 2014
*/
#pragma once

#include <vector>
#include <list>
#include "Taurus_Xml/XmlFunc.h"
#include "Taurus_Util/Macros.h"
#include "Taurus_Viewer/TBLayoutInfo.h"

//forward declarations
class CToolboxData;

/**
@brief  toolbar property
*/
class CToolbarProperty
{
private:
  /**
  @brief		default construtor
  */
  CToolbarProperty();

  DISALLOW_COPY_AND_ASSIGN(CToolbarProperty);

public:
  /**
  @brief		destructor
  */
  ~CToolbarProperty();

  /**
  @brief		get pointer to the single instance of toolbar property
  @return		pointer to the single instance of toolbar property
  */
  static CToolbarProperty* getInstance();

  /**
  @brief		import toolbar property xml node in viewer property
  @return		ERROR_SUCCESS if succeeds, an error code otherwise
  */
  DWORD importProperty();

  /**
  @brief		set preset toolbar position
  @param		enumPos toolbar position
  @return		ERROR_SUCCESS upon success, an error code otherwise
  */
  DWORD setPresetToolbarPos(ToolbarPosition enumPos);
  
  /**
  @brief		get preset toolbar position
  @return		toolbar position
  */
  inline ToolbarPosition getPresetToolbarPos() const
  {
    return m_enumPrestTBPos;
  }

  /**
  @brief		access to toolbar visibility
  @param		index the index number of monitor
  @param    visible variable in which the visibility of toolbar on a monitor is stored
  @return		ERROR_SUCCESS if succeeds, an error code otherwise
  */
  DWORD getTBVisibility(const unsigned int index, BOOL& bVisible) const;

  /**
  @brief		set the visibility of toolbar on a monitor
  @param		index the index number of monitor
  @param    visible flag indiciating visibility
  @return		ERROR_SUCCESS if succeeds, an error code otherwise
  */
  DWORD setTBVisibility(const unsigned int index, BOOL visible);

  /**
  @brief		applies function fn to each of tool data
  @param		fn unary function that accepts pointer to const toolbox data as argument
               if fn return false, this method stop applying fn
  */
  template<class Function>
  void forEachToolboxes(Function fn) const;

  /**
  @brief		get the number of toolbox data
  @return		the number of toolbox data
  */
  inline unsigned getNumToolboxes() const
  {
    return m_listToolboxes.size();
  }

  /**
  @brief		get hidden toolbar font property
  @param		resType monitor resoultion type
  */
  CFontProperty getHiddenToolbarFontProperty(MonitorResolutionType resType) const;

private:
  /**
  @brief		initialize toolbar property as default
  @return		ERROR_SUCCESS if succeeds, an error code otherwise
  */
  DWORD initToDefault();

  /**
  @brief		import toolbar property xml node
  @param		pPropertyNode pointer to  property xml node
  @param    bMuseUpdate variable in which whether property should be updated or not
  @return		ERROR_SUCCESS upon success, an error code otherwise
  */
  DWORD importProperty(MSXML2::IXMLDOMNodePtr pPropertyDoc, BOOL& bMustUpdate);

  /**
  @brief		initialize toolbox property to default
  @return		ERROR_SUCCESS upon success, an error codeo otherwise
  */
  DWORD initToolboxPropertiesToDefault();

  /**
  @brief		import toolbox property to custom
  @param		pPropertyNode pointer to toolboxes property
  @return		ERROR_SUCCESS upon success, an error code otherwise
  */
  DWORD importToolboxProperties(MSXML2::IXMLDOMNodePtr pPropertyNode);

  /**
  @brief		import toolbox propety and create toolbox data
  @param		pToolbox pointer to toolbx property node
  @param    pOutToolbox variable in which pointer to toolbox data is stored
  @return		
  */
  DWORD createCustomToolbox(MSXML2::IXMLDOMNodePtr pToolboxNode,
                            CToolboxData*& pOutToolbox);

  /**
  @brief		initialize preset toolbar position to default
  @return		ERROR_SUCCESS upon success, an error code otherwise
  */
  DWORD initPresetTBPosToDefault();

  /**
  @brief		import preset toolbar position to custom
  @param		pPropertyNode pointer to toolbar position property node
  @return		ERROR_SUCCESS upon success, an error code otherwise
  */
  DWORD importPresetTBPos(MSXML2::IXMLDOMNodePtr pPropertyNode);

  /**
  @brief		export current property to viewer property
  @return		ERROR_SUCCESS upon success, an error code otherwise
  */
  DWORD exportProperty();

  /**
  @brief		export current toolbox property to property xml node
  @param		pParentNode pointer to parent xml node which property xml node to be attached
  @return		ERROR_SUCCESS upon success, an error code otherwise
  */
  DWORD exportToolboxProperties(MSXML2::IXMLDOMNodePtr pParentNode);

  /**
  @brief		export current preset toolbar position to property xml node
  @param		pParentNode pointer to parent xml node which property xml node to be attached
  @return		ERROR_SUCCESS upon success, an error code otherwise
  */
  DWORD exportPresetTBPosProperty(MSXML2::IXMLDOMNodePtr pParentNode);
 
  /**
  @brief		destroy all of current properties
  */
  void destroyAllProperties();

  /**
  @brief		remove all toolbox properties
  */
  void removeAllToolboxProperties();

  private:

    //pointer to the single instance of toolbar property
    static CToolbarProperty* m_pInstance;

    //preset toolbar position
    ToolbarPosition m_enumPrestTBPos;

    //toolbar visibility
    std::vector<BOOL> m_theTBVisibilities;

    //toolbox data properties
    std::list<CToolboxData*> m_listToolboxes;
};

template<class Function>
void CToolbarProperty::forEachToolboxes(Function fn) const
{
  auto first = m_listToolboxes.cbegin();
  auto last  = m_listToolboxes.end();
  while(first != last)
  {
    if(!fn((const CToolboxData*)(*first))) break;
    ++first;
  }
}